package imp

import (
	sqlc "bgs/db/sqlc"
	brandFanGrpc "bgs/grpc/gen/service/brand_fan"
	"bgs/grpc/gen/shared/message"
	"context"
	"fmt"
)

/****************************************************************************************/
/*                               brand_fan entity of helper                              */
/****************************************************************************************/

func transformBrandFanEntityToPb(brandFan sqlc.BrandFan) *brandFanGrpc.BrandFanEntity {
	return &brandFanGrpc.BrandFanEntity{
		Id:             brandFan.ID,
		BrandId:        brandFan.BrandID,
		FollowerUserId: brandFan.FollowerUserID,
		BeFollowed:     sqlc.GoTimeToPBTimestamp(brandFan.BeFollowed),
		AliasName:      brandFan.AliasName,
		Remark:         brandFan.Remark.String,
	}
}

/****************************************************************************************/
/*                               brand_fan entity of cmd                                 */
/****************************************************************************************/

// UpsertBrandFan 创建品牌粉丝关系
func (s *BrandAPIService) UpsertBrandFan(ctx context.Context, req *brandFanGrpc.UpsertBrandFanRequest) (res *brandFanGrpc.UpsertBrandFanResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_fanImp->UpsertBrandFan:%v", req)
	res = &brandFanGrpc.UpsertBrandFanResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpsertBrandFanParams{
		BrandID:        req.BrandId,
		FollowerUserID: req.FollowerUserId,
		BeFollowed:     sqlc.PBTimestampToGoTime(req.BeFollowed),
		AliasName:      req.AliasName,
	}
	brandFan, err := s.dao.Q.UpsertBrandFan(ctx, arg)

	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandFan = transformBrandFanEntityToPb(brandFan)
	return
}

// UpdateBrandFan 更新品牌粉丝关系
func (s *BrandAPIService) UpdateBrandFan(ctx context.Context, req *brandFanGrpc.UpdateBrandFanRequest) (res *brandFanGrpc.UpdateBrandFanResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_fanImp->UpdateBrandFan:%v", req)
	res = &brandFanGrpc.UpdateBrandFanResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpdateBrandFanParams{
		ID:        req.Id,
		AliasName: req.AliasName,
		Remark:    sqlc.NSFromString(req.Remark),
	}
	brandFan, err := s.dao.Q.UpdateBrandFan(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandFan = transformBrandFanEntityToPb(brandFan)
	return
}

/****************************************************************************************/
/*                               brand_fan entity of query                               */
/****************************************************************************************/

// GetBrandFan 获取单个品牌粉丝
func (s *BrandAPIService) GetBrandFan(ctx context.Context, req *brandFanGrpc.GetBrandFanRequest) (res *brandFanGrpc.GetBrandFanResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_fanImp->GetBrandFan:%v", req)
	res = &brandFanGrpc.GetBrandFanResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	brandFan, err := s.dao.Q.GetBrandFan(ctx, req.Id)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandFan = transformBrandFanEntityToPb(brandFan)
	return
}

/****************************************************************************************/
/*                            brand_fanJoins entity of helper                           */
/****************************************************************************************/

func transformBrandFanWithUserStatEntityToPb(row sqlc.ListBrandFanWithUserAndUserStatsRow) *brandFanGrpc.BrandFanWithUserAndUserStatEntity {
	return &brandFanGrpc.BrandFanWithUserAndUserStatEntity{
		// brand_fan
		Id:             row.ID,
		BrandId:        row.BrandID,
		FollowerUserId: row.FollowerUserID,
		BeFollowed:     sqlc.GoTimeToPBTimestamp(row.BeFollowed),
		AliasName:      row.AliasName,
		Remark:         row.Remark.String,

		// user
		FollowerUserNickName: row.FollowerUserNickName,
		FollowerUserPic:      row.FollowerUserPic,

		// user_stat
		FansCount:            row.FansCount,
		FollowUserCount:      row.FollowUserCount,
		FollowBrandCount:     row.FollowBrandCount,
		FollowStoreCount:     row.FollowStoreCount,
		EndorseBrandCount:    row.EndorseBrandCount,
		EndorseStoreCount:    row.EndorseStoreCount,
		EndorseActivityCount: row.EndorseActivityCount,
		InvolveActivityCount: row.InvolveActivityCount,
		OrderCount:           row.OrderCount,
		ViewCount:            row.ViewCount,
		PayAmount:            row.PayAmount,
	}
}

func mapBrandFanWithUserAndUserStatEntityToPb(list []sqlc.ListBrandFanWithUserAndUserStatsRow, f func(sqlc.ListBrandFanWithUserAndUserStatsRow) *brandFanGrpc.BrandFanWithUserAndUserStatEntity) []*brandFanGrpc.BrandFanWithUserAndUserStatEntity {
	r := make([]*brandFanGrpc.BrandFanWithUserAndUserStatEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                            brand_fanJoins entity of query                             */
/****************************************************************************************/

// ListBrandFanWithUserAndUserStats  获取粉丝及用户和其统计信息
func (s *BrandAPIService) ListBrandFanWithUserAndUserStats(ctx context.Context, req *brandFanGrpc.ListBrandFanWithUserAndUserStatsRequest) (res *brandFanGrpc.ListBrandFanWithUserAndUserStatsResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_fanImp->ListBrandFanWithUserAndUserStats:%v", req)

	res = &brandFanGrpc.ListBrandFanWithUserAndUserStatsResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}

	q := s.dao.Q
	ts := sqlc.PBTimestampToGoTime(req.Ts)
	brandID := req.BrandId
	keyword := req.Keyword
	isKeywordEmpty := keyword == ""
	keywordLike := fmt.Sprintf("%%%s%%", keyword)

	total, err := q.CountBrandFanWithUserAndUserStats(ctx, sqlc.CountBrandFanWithUserAndUserStatsParams{
		Created:        ts,
		BrandID:        brandID,
		IsKeywordEmpty: isKeywordEmpty,
		Keyword:        keywordLike,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}

	brandFanWithUserAndUserStats, err := q.ListBrandFanWithUserAndUserStats(ctx, sqlc.ListBrandFanWithUserAndUserStatsParams{
		Limit:          req.Limit,
		Offset:         req.Offset,
		Created:        ts,
		BrandID:        brandID,
		IsKeywordEmpty: isKeywordEmpty,
		Keyword:        keywordLike,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.BrandFanWithUserStats = mapBrandFanWithUserAndUserStatEntityToPb(brandFanWithUserAndUserStats, transformBrandFanWithUserStatEntityToPb)
	return
}
